﻿using System;
using System.Diagnostics;

using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;
using Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;

namespace BizElements.BusinessLayer
{
    /// <summary>A <see cref="System.Diagnostics.TraceListener"/> that delivers the trace data 
    /// to the <b>BizElements.Services/WsLogReceiver.asmx</b> Web service, 
    /// formatting the output with an <see cref="ILogFormatter"/>.</summary>
    [ConfigurationElementType(typeof(FormattedWebServiceTraceListenerData))]
    public class FormattedWebServiceTraceListener : FormattedTraceListenerBase
    {
        #region Fields.

        string url;

        #endregion

        #region CTor.

        /// <summary>
        /// Initializes a new instance of <see cref="FormattedWebServiceTraceListener"/>.
        /// </summary>
        /// <param name="url">URL of the <b>WsLogReceiver.asmx</b> Web service.</param>
        /// <param name="formatter">The formatter.</param>    
        public FormattedWebServiceTraceListener(string url, ILogFormatter formatter)
            : base(formatter)
        {
            if (string.IsNullOrEmpty(url))
                throw new ArgumentNullException("url", "URL of the WsLogReceiver.asmx Web service is required.");

            this.url = url;
        }

        #endregion

        #region TraceData, Write, WriteLine.

        /// <summary>Delivers the trace data to the <b>BizElements.Services/WsLogReceiver.asmx</b> Web service.</summary>
        /// <param name="eventCache">The context information provided by <see cref="System.Diagnostics"/>.</param>
        /// <param name="source">The name of the trace source that delivered the trace data.</param>
        /// <param name="eventType">The type of event.</param>
        /// <param name="id">The id of the event.</param>
        /// <param name="data">The <see cref="LogEntry"/> object to trace. Ignored if not an instance of LogEntry class.</param>
        public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data)
        {
            // Only LogEntry data is supported.
            LogEntry logEntry = data as LogEntry;
            if (logEntry != null)
            {
                byte[] serializedLogEntry = Serializer.SerializeWithBinaryFormater(logEntry);
                WsLogSender remoter = new WsLogSender();
                remoter.Url = this.url;
                remoter.WriteLogEntry(serializedLogEntry);
                InstrumentationProvider.FireTraceListenerEntryWrittenEvent();
            }
        }

        /// <summary>
        /// Does nothing.
        /// </summary>
        /// <param name="message">The message to log. Ignored.</param>
        public override void Write(string message)
        {
        }

        /// <summary>
        /// Does nothing.
        /// </summary>
        /// <param name="message">The message to log. Ignored.</param>
        public override void WriteLine(string message)
        {
            Write(message);
        }

        #endregion
    }
}